define([
    "firebug/lib/object",
    "firebug/lib/system",
    "firebug/lib/css"
], function(Obj, System, Css) {

var {classes: Cc, interfaces: Ci, utils: Cu} = Components;

Firebug.NetCopy = Obj.extend(Firebug.Module, {

	dispatchName: "netCopy",
	filterDomain: false,

    initialize: function(owner){
		this.versioncmp = this.Utils.cmpversions(Firebug.currentVersion, [2,0,1,0]);
		if(this.versioncmp === -1 ){
			alert("The NetCopy extension requires a least Firebug 2.0.1 .\nUpdate Firebug if you want to use it.");
			return;
		}
        Firebug.Module.initialize.apply(this, arguments);
		Firebug.NetMonitor.NetRequestTable.addListener(this);
		this.overlay_netpanel();
    },

    shutdown: function(){
		if(this.versioncmp === -1 )
			return;
        Firebug.Module.shutdown.apply(this, arguments);
		Firebug.NetMonitor.NetRequestTable.removeListener(this);
		this.clean_netpanel();
    },
	
	getSettings: function(){
		return this.__settings__ || (this.__settings__ = (new Firebug.NetCopy.Settings()).restore());
	},
	
    clean_netpanel: function() {
		var doc = Firebug.chrome.window.document;
		var fbNetButtons = doc.getElementById('fbNetButtons');
		var fbNetButtonsFilter = doc.getElementById('fbNetButtonsFilter');
		fbNetButtons.removeChild(doc.getElementById('netcopy-expandall'));
		fbNetButtons.removeChild(doc.getElementById('netcopy-menu-copy'));
		fbNetButtonsFilter.removeChild(doc.getElementById('netcopy-filterdomain'));
	},
	
    overlay_netpanel: function() {
		var doc = Firebug.chrome.window.document;
		var fbNetButtons = doc.getElementById('fbNetButtons');

		//Add expend all button
		var bt_expandall = document.createElement('toolbarbutton');
			bt_expandall.setAttribute('id', 'netcopy-expandall');
			bt_expandall.setAttribute('label', '+');
			bt_expandall.setAttribute('class', 'toolbar-text-button');
			bt_expandall.setAttribute('tooltiptext', 'Expand/reduce all pages');
			bt_expandall.setAttribute('oncommand', 'Firebug.NetCopy.onExpandeAllPages()');
			fbNetButtons.insertBefore(bt_expandall, doc.getElementById('fbNetClear'));

		//Add Domain filter button
		var bt_domain = document.createElement('toolbarbutton');
			bt_domain.setAttribute('id', 'netcopy-filterdomain');
			bt_domain.setAttribute('label', 'Domain');
			bt_domain.setAttribute('class', 'toolbar-text-button');
			bt_domain.setAttribute('type', 'checkbox');
			bt_domain.setAttribute('tooltiptext', 'Show only requests with a domain identique to the page');
			bt_domain.setAttribute('oncommand', 'Firebug.NetCopy.onToggleFilterDomain(this)');
			doc.getElementById('fbNetButtonsFilter').insertBefore(bt_domain, doc.getElementById('fbNetFilter-all'));

		//Add copy menu button
		var bt_copy = document.createElement('toolbarbutton');
			bt_copy.setAttribute('id', 'netcopy-menu-copy');
			bt_copy.setAttribute('label', ' Copy ');
			bt_copy.setAttribute('class', 'toolbar-text-button');
			bt_copy.setAttribute('type', 'menu-button');
			bt_copy.setAttribute('tooltiptext', 'Copy the formated requests only to clipboard (short formatting)');
			bt_copy.setAttribute('oncommand', 'if(this == event.target) Firebug.NetCopy.doCopyAll(Firebug.currentContext, false, false);');

			var bt_menupopup = document.createElement('menupopup');

				var bt_copyscript = document.createElement('menuitem');
					bt_copyscript.setAttribute('id', 'netcopy-menu-copyfull');
					bt_copyscript.setAttribute('label', 'Copy requests');
					bt_copyscript.setAttribute('class', 'toolbar-text-button');
					bt_copyscript.setAttribute('tooltiptext', 'Copy the formated requests to the clipboard (full formatting)');
					bt_copyscript.setAttribute('oncommand', 'Firebug.NetCopy.doCopyAll(Firebug.currentContext, true, false);');
					bt_menupopup.appendChild(bt_copyscript);

				var bt_savescript = document.createElement('menuitem');
					bt_savescript.setAttribute('id', 'netcopy-menu-savescript');
					bt_savescript.setAttribute('label', 'Save requests as ...');
					bt_savescript.setAttribute('class', 'toolbar-text-button');
					bt_savescript.setAttribute('tooltiptext', 'Save the formated requests in a file (full formatting)');
					bt_savescript.setAttribute('oncommand', 'Firebug.NetCopy.doCopyAll(Firebug.currentContext, true, true);');
					bt_menupopup.appendChild(bt_savescript);
					
				bt_menupopup.appendChild(document.createElement('menuseparator'));
				
				var bt_filters = document.createElement('menu');
					bt_filters.setAttribute('id', 'netcopy-menu-filter');
					bt_filters.setAttribute('label', 'Filter');
					bt_filters.setAttribute('class', 'toolbar-text-button');
					bt_filters.setAttribute('oncommand', "Firebug.NetCopy.onRadioSettingsChange('filterIndex', event.target)");
					var bt_filters_popup = document.createElement('menupopup');
						bt_filters_popup.setAttribute("onpopupshowing", "Firebug.NetCopy.doCreateRadioSettings('filterIndex', 'filters', this)");
						bt_filters.appendChild(bt_filters_popup);
					bt_menupopup.appendChild(bt_filters);
					
				var bt_templates = document.createElement('menu');
					bt_templates.setAttribute('id', 'netcopy-menu-template');
					bt_templates.setAttribute('label', 'Template');
					bt_templates.setAttribute('class', 'toolbar-text-button');
					bt_templates.setAttribute('oncommand', "Firebug.NetCopy.onRadioSettingsChange('templateIndex', event.target)");
					var bt_templates_popup = document.createElement('menupopup');
						bt_templates_popup.setAttribute("onpopupshowing", "Firebug.NetCopy.doCreateRadioSettings('templateIndex', 'templates', this)");
						bt_templates.appendChild(bt_templates_popup);
					bt_menupopup.appendChild(bt_templates);

				var bt_settings = document.createElement('menuitem');
					bt_settings.setAttribute('id', 'netcopy-menu-settings');
					bt_settings.setAttribute('label', 'Settings ...');
					bt_settings.setAttribute('class', 'toolbar-text-button');
					bt_settings.setAttribute('oncommand', 'Firebug.NetCopy.onSettings()');
					bt_menupopup.appendChild(bt_settings);
				
				bt_menupopup.appendChild(document.createElement('menuseparator'));

				var bt_about = document.createElement('menuitem');
					bt_about.setAttribute('id', 'netcopy-menu-about');
					bt_about.setAttribute('label', 'About ...');
					bt_about.setAttribute('class', 'toolbar-text-button');
					bt_about.setAttribute('oncommand', 'Firebug.NetCopy.onAbout(Firebug.currentContext);');
					bt_menupopup.appendChild(bt_about);

				bt_copy.appendChild(bt_menupopup);
			fbNetButtons.insertBefore(bt_copy, doc.getElementById('fbNetPersist').nextSibling);
	},
	
		
    onRadioSettingsChange: function(att_sel, element) {
		var index = 0;
		while(element = element.previousSibling)
			index++;
		var settings = this.getSettings();
		settings[att_sel] = index;
		settings.save();
	},
	
    doCreateRadioSettings: function(att_sel, att_name, popup) {
		while (popup.firstChild)
			popup.removeChild(popup.firstChild);
		var doc = popup.ownerDocument;
		var settings = this.getSettings();
		var index = settings[att_sel];
		settings[att_name].map((e,i)=>{
			 var item = doc.createElement('menuitem');
			 item.setAttribute('label', e.name);
			 item.setAttribute('type', 'radio');
			 if(i === index)
				item.setAttribute('checked', true);
			 popup.appendChild(item);
		 });
	},
	
	onCreateRequestEntry: function(sender, row){
		var req = row.repObject;
		if(row.repObject.requestNumber == 1)
		   this.mainhost = Firebug.currentContext.global.location.host;
		if(this.mainhost != row.repObject.request.URI.host){
			Css.setClass(row, "category-domain");
			row.repObject.isDomain = false;
		}else{
			row.repObject.isDomain = true;
		}
	},
	
    onShowPanel: function(panel){
		if(this.filterDomain)
			Css.setClass(panel.panelNode, "hideCategory-domain");
    },

    initContext: function(context) {
		//Hook getContextMenuItems to onGetContextMenuItems
		var self = this;
		var netPanel = context.panelMap.net;
		var fn_getContextMenuItems = netPanel.getContextMenuItems;
		netPanel.getContextMenuItems = function(nada, target){
			var items = fn_getContextMenuItems.call(netPanel, nada, target);
			var request = Firebug.getRepObject(target);
			self.onGetContextMenuItems.call(self, items, request);
			return items;
		};
    },
	
	onGetContextMenuItems: function(menuItems, request) {
		if(!request)
			return;
		var curlindex = this.Utils.arrindex(menuItems, (e) => e['id'] === 'fbCopyAsCurl' );
		menuItems.splice(curlindex + 1, 0, {
			id: "netCopy.contextmenu",
			label: "Copy Request",
			tooltiptext: "Copy the request to the defined format",
			command: Obj.bindFixed(this.doCopyOne, this, Firebug.currentContext, request)
		});
	},

	doCopyOne: function(context, request) {
		var text;
		try{
			text = this.format(context, [[request]], false, false);
		}catch(ex){
			text = 'Exception: ' + ex.message + '\n' + ex.stack;
			alert(text);
		}
		System.copyToClipboard(text);
	},
	
	doCopyAll: function(context, fullFormat, to_file) {
		try{
			var pages = [];
			var netPanel = context.panelMap.net;
			var tbody = netPanel.table && netPanel.table.querySelector(".netTableBody");
			if(tbody){
				var categories = netPanel.filterCategories;
				if (categories.indexOf('all') === -1){
					if (this.filterDomain)
						var fn_match_category = (file) => file.isDomain && file.categories.some((category) => categories.indexOf(category) !== -1);
					else
						var fn_match_category = (file) => file.categories.some((category) => categories.indexOf(category) !== -1);
				}else if (this.filterDomain){
					var fn_match_category = (file) => file.isDomain;
				}else{
					var fn_match_category = (file) => true;
				}
				var fn_comp_files = (fa, fb)=> fa.startTime - fb.startTime;
				var cur_reqs = [];
				var row = tbody.firstChild;
				while(row){
					var rowcls = row.className;
					if(rowcls.indexOf('netRow') != -1){
						if(rowcls.indexOf('netPageRow') != -1 && row.files){
							var prev_reqs = [];
							var obj_files = row.files;
							for (var i=0; i<obj_files.length; i++){
								if( fn_match_category(obj_files[i].file) )
								   prev_reqs.push(obj_files[i].file);
							}
							prev_reqs.sort(fn_comp_files);
							pages.push(prev_reqs);
						}else if(rowcls.indexOf('history') == -1 && row.repObject){
						   if( fn_match_category(row.repObject) )
							  cur_reqs.push(row.repObject);
						}
					}
					row = row.nextSibling;
				}
				cur_reqs.sort(fn_comp_files);
				pages.push(cur_reqs);				
			}
			var text = this.format(context, pages, fullFormat, true);
			if(to_file)
				this.Utils.save_text_filepicker(window, text);
			else
				System.copyToClipboard(text);
		}catch(ex){
			alert( 'Exception: ' + ex.message + '\n' + ex.stack);
		}
    },
	
	onToggleFilterDomain: function(item) {
		var panelNet = Firebug.currentContext.panelMap.net;
		if(this.filterDomain = item.getAttribute('checked') ? true : false)
			Css.setClass(panelNet.panelNode, "hideCategory-domain");
		else
			Css.removeClass(panelNet.panelNode, "hideCategory-domain");
	},	
	
	onExpandeAllPages: function() {
		var netPanel = Firebug.currentContext.panelMap.net;
		var pageRows = netPanel.panelNode.getElementsByClassName('netPageRow');
		for (var r=0; r<pageRows.length; r++){
			var pageRow = pageRows[r];
			if (!Css.hasClass(pageRow, "opened")){
				Css.setClass(pageRow, "opened");
				var files = pageRow.files;
				netPanel.insertRows(files, pageRow);
				for (var i=0; i<files.length; i++)
					netPanel.queue.push(files[i].file);
				netPanel.layout();
			}else{
				Css.removeClass(pageRow, "opened");
				var nextRow = pageRow.nextSibling;
				while (!Css.hasClass(nextRow, "netPageRow") && !Css.hasClass(nextRow, "netPageSeparatorRow")) {
					var nextSibling = nextRow.nextSibling;
					nextRow.parentNode.removeChild(nextRow);
					nextRow = nextSibling;
				}
			}
		}
	},
	
	onSettings: function(item) {
		if (null == this.settingsDialog || this.settingsDialog.closed)
			this.settingsDialog = window.openDialog( 'chrome://netcopy/content/settings.xul', '', "modal,centerscreen,resizable", Firebug.NetCopy, this.getSettings());
		this.settingsDialog.focus();
    },
	
    onAbout: function(context) {
		AddonManager.getAddonByID("netcopy@florentbr", (addon)=>openDialog("chrome://mozapps/content/extensions/about.xul", "", "chrome,centerscreen,modal", addon) );
    },
	
	format: function(context, pages, fullFormat, allowFilters) {

		Http = Firebug.require("firebug/lib/http");
		var settings = this.getSettings();
		var filters = settings.filters[settings.filterIndex];
		var template = settings.templates[settings.templateIndex];
		
		var encoder = new Firebug.NetCopy.Encoder( template.replace_what.split(','), template.replace_by.split(','));
		var re_url_include = new RegExp(filters.urls_include.join('|'));
		var re_url_exclude = filters.urls_exclude.length && new RegExp(filters.urls_exclude.join('|'));
		var re_content_include = new RegExp(filters.contents_include.join('|'));
		var re_content_exclude = filters.contents_exclude.length && new RegExp(filters.contents_exclude.join('|'));
		var globHost = context.global.location.host;
		var globHostUrl = context.global.location.origin;
		var prefs_methods = {'GET':template.method_get, 'PUT':template.method_put, 'POST':template.method_post, 'PATCH':template.method_patch, 
				  'DELETE':template.method_delete, 'OPTIONS':template.method_options, 'HEAD': template.method_head};
		var txt_static_headers = template.header_glob_start + this.Utils.objmap(filters.headers_global, 
				(k,v) => template.header_glob_item.replace('$name', k).replace('$value', encoder.encodeData(v))
			).join(template.header_glob_sep) + template.header_glob_end;

		if(!this.reqCpt || (fullFormat && allowFilters))
			this.reqCpt = 0;
		var txt_pages = '', txt_requests = '';
		for(var p=0; p<pages.length; p++){
			if(p!=0)
				txt_requests = fullFormat ? '' : txt_requests + '\n';
			var requests = pages[p];
			var txt_page_title = (requests && requests.length != 0 && requests[0].document.title) || '';
			var txt_page_name = txt_page_title.replace(/[^\w_]+/g, '_');
			for(var r=0; r<requests.length; r++){
				var request = requests[r];
				var reqHost = request.request.URI.host;
				var reqIsExtrenal = reqHost != globHost;
				var reqUrl = request.href;
				var reqType = request.mimeType;
				var reqPostData = request.postText || Http.readPostTextFromRequest(request.request, context) || Http.readPostTextFromPage(request.href, context);
				var reqHeaders = {};
				if(request.requestHeaders){
					var hds = request.requestHeaders.concat(Http.getHeadersFromPostText(request.request, reqPostData));
					for(var h in hds){
					   if(hds.hasOwnProperty(h) && !this.Utils.arrany(filters.headers_exclude, hds[h].name) )
						   reqHeaders[hds[h].name] = hds[h].value;
					}
				}
				
				if(allowFilters){
					if(filters.domainonly && reqIsExtrenal)
						continue;
					if(!re_url_include.test(reqUrl) || re_url_exclude && re_url_exclude.test(reqUrl) )
						continue;
					if(!re_content_include.test(reqType) || re_content_exclude && re_content_exclude.test(reqType) )
						continue;
				}
				
				var txt_req_headers = this.Utils.objany(reqHeaders) && template.header_req_start + this.Utils.objmap(reqHeaders, 
						(k,v)=>template.header_req_item.replace('$name', k).replace('$value', encoder.encodeData(v))
					).join(template.header_req_sep) + template.header_req_end;
					
				var txt_req_data = reqPostData && template.data.replace('$value', reqPostData.length < 1024 ? encoder.encodeData(reqPostData) : '!!! Too long !!!' );
					
				txt_requests += template.requests
					.replace('$reqmethod', prefs_methods[request.method] || '')
					.replace('$reqpath', encoder.encodeUrl(reqIsExtrenal ? request.href : request.request.URI.path))
					.replace('$requrl', encoder.encodeUrl(request.href))
					.replace('$reqtype', reqType)
					.replace('$reqheaders', txt_req_headers || '')
					.replace('$reqcpt', (this.reqCpt++).toString() )
					.replace('$pagetitle', txt_page_title)
					.replace('$pagename', txt_page_name)
					.replace('$respstatus', request.responseStatus)
					.replace('$respsize', (request.size / 1024).toFixed(2) )
					.replace('$totaltime', request.endTime - request.startTime)
					.replace('$blockingtime', request.resolvingTime - request.startTime)
					.replace('$resolvingtime', request.connectingTime - request.resolvingTime)
					.replace('$connectingtime', request.sendingTime - request.connectingTime)
					.replace('$sendingtime', request.waitingForTime - request.sendingTime)
					.replace('$waitingtime', request.respondedTime - request.waitingForTime)
					.replace('$receivingtime', request.endTime - request.respondedTime)
					.replace('$servertime', request.endTime - request.connectedTime)
					.replace('$reqdata', txt_req_data || '');
			}
			if(fullFormat)
				txt_pages += template.pages
					.replace('$requests', txt_requests)
					.replace('$pagetitle', txt_page_title)
					.replace('$pagename', txt_page_name);
		}
		if(fullFormat)
			return template.content
				.replace('$stdheaders', txt_static_headers)
				.replace('$pages', txt_pages)
				.replace('$hosturl', encoder.encodeUrl(globHostUrl));
		return txt_requests.replace(/\n$/g, '');
	},
		
});

Firebug.NetCopy.Encoder = function (lst_what, lst_to){

	this.__map__ = [];
	var min_len = Math.min( lst_what.length, lst_to.length);
	for(var i=0; i<min_len; i++)
		this.__map__.push([new RegExp(lst_what[i], 'g'), lst_to[i]]);
	
	this.encodeUrl = function(text) {
		return text.replace(/[^A-z0-9_\%\-!.~'()*,;:$&+=?\/\[\]@]/g,  this._encurlchar_ );
	};
	
	this.encodeData = function(text) {
		for(var i=0; i<this.__map__.length; i++)
			text = text.replace(this.__map__[i][0], this.__map__[i][1]);
		return text.replace(/[^\x20-\x7E]/g, this._encdatachar_);
	};
	
	this._encurlchar_ = function(c){
		var code = c.charCodeAt(0);
		return (code < 16 ? "%0" : "%") + code.toString(16).toUpperCase();
	};
	
	this._encdatachar_ = function(c){
		var code = c.charCodeAt(0);
		if (code < 256)
			return (code < 16 ? "\\x0" : "\\x") + code.toString(16).toUpperCase();
		code = code.toString(16);
		return "\\u" + ("0000" + code).slice(-4).toUpperCase();
	};
};

Firebug.NetCopy.Settings = function(){
	
	this.filterIndex = 0;
	this.templateIndex = 0;
	this.tabIndex = 0;
	this.filters = [];
	this.templates = [];

};

Firebug.NetCopy.Settings.prototype = {

	 default_filter: function(){
		return {
			name: 'default',
			headers_exclude : ['host', 'user-agent', 'accept', 'accept-language', 'accept-encoding', 'cookie', 'referer', 'connection', 'cache-control'],
			headers_global : {
				'User-Agent' : navigator.userAgent,
				'Accept' : Application.prefs.get('network.http.accept.default').value,
				'Accept-Language' : navigator.language.replace(/^(([^-]+)-.*)/, '$1,$2;q=0.5'),
				'Accept-Encoding' : Application.prefs.get('network.http.accept-encoding').value
			},
			domainonly: false,
			urls_include: ['.*'],
			urls_exclude: [],
			contents_include: ['.*'],
			contents_exclude: [],
		};
	},
	
	save: function(modified){
		if(modified){
			var data = { filters: this.filters, templates: this.templates};
			var datastr = JSON.stringify(data, null, '  ');
			var file = Firebug.NetCopy.Utils.get_file(["ProfD", "netcopy", "settings.json"]);
			Firebug.NetCopy.Utils.write_file(file, datastr);
		}
		Application.prefs.setValue('extensions.firebug.netcopy.filterIndex', this.filterIndex);
		Application.prefs.setValue('extensions.firebug.netcopy.templateIndex', this.templateIndex);
		Application.prefs.setValue('extensions.firebug.netcopy.tabIndex', this.tabIndex);
		return this;
	},
	
	restore : function(){
		var file = Firebug.NetCopy.Utils.get_file(["ProfD", "netcopy", "settings.json"]);
		if(file.exists()){
			var data = JSON.parse(Firebug.NetCopy.Utils.read_file(file));
			this.filters = data.filters;
			this.templates = data.templates;
		}else{
			this.reset();
		}
		this.filterIndex = Application.prefs.getValue('extensions.firebug.netcopy.filterIndex', 0);
		this.templateIndex= Application.prefs.getValue('extensions.firebug.netcopy.templateIndex', 0);
		this.tabIndex= Application.prefs.getValue('extensions.firebug.netcopy.tabIndex', 0);
		return this;
	},
	
	reset: function(){
		var data = JSON.parse(Firebug.NetCopy.Utils.read_url('chrome://netcopy/content/settings.json'));
		this.filterIndex = this.templateIndex = 0;
		this.filters = [this.default_filter()].concat(data.filters);
		this.templates = data.templates;
	},
	
	update: function(source){
		for(var k in this){
			if(this.hasOwnProperty(k) && k[0] != '_' && source.hasOwnProperty(k) && typeof this[k] !== 'function')
				this[k] = source[k];
		}
	},
	
	merge: function(source){
		for(var k in this){
			if(this.hasOwnProperty(k) && k[0] != '_' && source.hasOwnProperty(k) && typeof this[k] !== 'function'){
				if(Array.isArray(this[k])){
					var arrsrc = source[k];
					var arrtarg = this[k];
					for(var i=0; i<arrsrc.length; i++){
						for(var j=0; j<arrtarg.length; j++){
							if(arrtarg[j].name === arrsrc[i].name){
								arrtarg[j] = arrsrc[i];
								break;
							}
						}
						if(j === arrtarg.length)
							arrtarg.push(arrsrc[i]);
					}
				}else{
					this[k] = source[k];
				}
			}
		}
	},

};

Firebug.NetCopy.Utils = {

	arrindex: function(array, callback){
		for(var i = 0; i < array.length; i++){
			if(callback(array[i], i))
				return i;
		}
		return -1;
	},
	
	objmap: function(obj, callback){
		var ret = [];
		for(var k in obj){
			if(obj.hasOwnProperty(k))
				ret.push(callback(k, obj[k]));
		}
		return ret;
	},

	objany: function(obj){
		for (var k in obj) {
			if (obj.hasOwnProperty(k))
			   return true;
		}
		return false;
	},

	objfields: function(obj){
		for(var k in obj){
			if(obj.hasOwnProperty(k) && k[0] != '_' && typeof obj[k] !== 'function')
				yield k;
		}
	},

	arrany: function(array, value){
		value = value.toLowerCase();
		for(var i = 0; i < array.length; i++) {
			if(array[i].toLowerCase() === value)
				return true;
		}
		return false;
	},

	clone: function(obj){
		var newobj = new obj.constructor();
		for(var k in obj){
			var v = obj[k];
			newobj[k] = typeof v === 'object' ? this.clone(v) : v;   
		}
		return newobj;
	},

	cmpversions: function(verstr, refarr){
		arr = verstr.split('.');
		var len = Math.min(arr.length, refarr.length);
		for(var i=0; i<len; i++){
			if(arr[i] > refarr[i])
			   return 1;
			else if(arr[i] < refarr[i])
			   return -1;
		}
		return 0;
	},
	
	get_file: function(arr_path){
		var path = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get(arr_path[0], Ci.nsIFile);
		for(var i=1; i<arr_path.length - 1; i++){
			path.append(arr_path[i]);
			if(!path.exists())
				path.create(1, 0666);
		}
		path.append(arr_path[i]);
		return path;
	},
	
	get_unique_name: function(base_name, list_of_names){
		var basename = base_name.replace(/\d+$/, '');
		var tryname = basename + '1';
		var i = 1;
		while(list_of_names.indexOf(tryname) != -1)
			tryname = basename + (++i).toString();
		return tryname
	},

	save_text_filepicker: function(owner, text){
		var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
		fp.init(owner, "Save As", Ci.nsIFilePicker.modeSave);
		fp.appendFilters(Ci.nsIFilePicker.filterAll);
		var res = fp.show();
		if (res != Ci.nsIFilePicker.returnCancel)
		  this.write_file(fp.file, text);
	},

	get_text_filepicker: function(owner){
		var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
		fp.init(owner, "Open", Ci.nsIFilePicker.modeOpen);
		fp.appendFilters(Ci.nsIFilePicker.filterAll);
		var res = fp.show();
		if (res != Ci.nsIFilePicker.returnCancel)
		   return this.read_file(fp.file, content);
	},

	write_file: function(nsIFile, data){
		var fs = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
		fs.init(nsIFile, 0x02 | 0x08 | 0x20, 0666, 0); 
		var cs = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
		cs.init(fs, "UTF-8", 0, 0);
		cs.writeString(data);
		cs.close();
	},

	read_file: function(nsIFile){
		var fs = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
		var cs = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
		fs.init(nsIFile, -1, 0, 0);
		cs.init(fs, "UTF-8", 0, 0);
		var txt = '';
		let (str = {}) {
			let read = 0;
			do { 
				read = cs.readString(0xffffffff, str);
				txt += str.value;
			} while (read != 0);
		}
		cs.close();
		return txt;
	},

	read_url: function(url){
		var io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
		var ss = Cc["@mozilla.org/scriptableinputstream;1"].getService(Ci.nsIScriptableInputStream);
		var ic = io.newChannel(url,null,null).open();
		ss.init(ic);
		var txt = ss.read(ic.available());
		ss.close();
		ic.close();
		return txt;
	},

};

return Firebug.NetCopy;

});
